<?php
/**
 * Created by PhpStorm.
 * User: Usr
 * Date: 2018/6/21
 * Time: 8:20
 */

require_once 'config.php';
require_once 'mysqli_api.php';
require_once 'pub.php';
require_once 'func.php';
require_once 'generate.php';
require 'vendor/autoload.php';
require 'Storage.php';
require 'ask.php';
require 'control.php';

$my_conn = my_conn(); // 实例化一个数据库连接
$mongo = mongodb(); // 实例化mongo连接
$storage = new Storage($tempfs, 'stock'); // 实例化Storage

echo "启动中……\n";

// 更新股票基本信息
$stock = re_stock($my_conn, $mongo); // 更新并获取股票基本信息
// 更新行权数据
$exright = re_exright($my_conn, $mongo);

$server = new swoole_websocket_server('0.0.0.0', 9905);
$server->set(array(
    'worker_num' => 3, // 工作进程数量
    'task_worker_num' => 1, // 异步任务进程数量
    'pid_file' => __DIR__ . '/server.pid',
//    'daemonize' => 1, // 进程守护模式
));

$server->on("request", function ($request, $http) {
    $request_uri = ltrim($request->server['request_uri'], '/');
    // 过滤浏览器icon请求
    if ($request_uri === 'favicon.ico') {
        return $http->end("");
    }

    // 请求参数
    if ($request->server['request_method'] === 'POST') {
        $params = $request->post;
    } else {
        $params = $request->get;
    }
    $response = [];
    switch ($request_uri) {

    }

    $http->end($response);

});

$server->on('open', function ($server, $req) {
    preg_match('/\/([a-zA-Z_]*)\/([a-zA-Z0-9+\/]*)/', $req->server['request_uri'], $request, PREG_OFFSET_CAPTURE);
    if (!isset($request[1][0]) || empty($request[2][0])) {
        echo '参数获取有误:' . $req->server['request_uri'] . PHP_EOL;
        return;
    }

    $fd = $req->fd;
    $sn = $request[2][0];

    if ($sn != 'f739cI5M6gbzGfS2950J2MF0wVnygHDfGRA6gvTeNQ') { // 签名认证失败，断开连接
        $server->close($fd);
    }

    switch ($request[1][0]) {
        case 'stat': // WEB端连接成功，把fd加入队列
            $stat_fd = $server->storage->get('stat/fd');
            $stat_fd[] = $fd;
            $server->storage->set('stat/fd', $stat_fd);
            if ($server->storage->get('stat/status') == 3) {
                msgToClient($fd, 'success', ['msg' => '运行状态异常，请联系管理员']);
            } elseif ($server->storage->get('stat/status') == 1) {
                msgToClient($fd, 'success', ['msg' => '正在运行']);
            } else {
                msgToClient($fd, 'success', ['msg' => '没有任务在运行']);
            }
            msgToClient($fd, 'open', ['msg' => '服务器连接成功']);
            break;
    }
});

$server->on('message', function ($server, $frame) {
    $fd = $frame->fd;
    $data = $frame->data;
    if ($data == 'restart') {
        if ($server->storage->get('stat/status') == 3) {
            msgToClient($fd, 'qing', ['msg' => '运行状态异常，请联系管理员']);
        } elseif ($server->storage->get('stat/status') == 1) {
            msgToClient($fd, 'qing', ['msg' => '有任务正在运行，如果长时间未响应，请联系管理员']);
        } else {
            // 当前运行状态
            $server->storage->set('stat/status', '1');

        }
        msgToClient($fd, 'qing', ['msg' => '启动完成']);
    }
});

$server->on('close', function ($server, $fd) {
    // 删除队列中的fd
    $stat_fd = $server->storage->get('stat/fd');
    if ($stat_fd) {
        $key = array_search($fd, $stat_fd);
        array_splice($stat_fd, $key, 1);
        $server->storage->set('stat/fd', $stat_fd);
    }
});

$server->on('WorkerStart', function ($server, $worker_id) {
    global $storage;
    $server->storage = $storage;

    if ($worker_id == 0) {
        echo "服务启动成功，运行参数：\n";
        print_r($server->setting); // 打印运行参数

        // 清除fd
        if ($server->storage->exists('stat/fd')) {
            $server->storage->del('stat/fd');
        }
        // 当前运行状态
        $server->storage->set('stat/status', '1');

        // 初始化
        init(my_conn(), mongodb());

        $server->task(['type' => 'invoke'], 0); // 必须顺序执行消息队列，指定投递到同一个任务进程
        // 启动定时器，每100秒执行一次
        swoole_timer_tick(1000 * 100, function () use ($server) {
            // 投递异步任务，执行检查流程控制表
            $server->task(['type' => 'invoke'], 0); // 必须顺序执行消息队列，指定投递到同一个任务进程
        });
    }
});

$server->on('task', function ($server, $task_id, $src_worker_id, $data) {
    switch ($data['type']) { // 任务类型
        // 检查流程控制表
        case 'invoke':
            echo "查询invoke表，时间：".date('Y-m-d H:i:s')."\n";
            stat_broadcast("查询invoke表，时间：".date('Y-m-d H:i:s'));
            invoke(my_conn(), mongodb());
            break;

        case 'stat_broadcast':
            stat_broadcast($data['msg']);
            break;

        default:
    }
});

$server->on('finish', function ($server, $task_id, $data) {

});

$server->start();
